﻿<%@ WebHandler Language="C#" Class="RequestHandler" %>

///////////////////////////////////////////////////////////////////////
//  Copyright (C) 2009 Kingsoft - All Rights Reserved
//
//  FileName : RequestHandler.ashx
//  Version : 1.0
//  Creater : Chen Shicai
//  Date : 2009/09/08
//  Comment :   
///////////////////////////////////////////////////////////////////////
using System;
using System.Reflection;
using System.Web;
using System.Web.SessionState;
using System.Collections.Generic;

public class RequestHandler : IHttpHandler, IRequiresSessionState
{
    /// <summary>
    /// Method指定的函数所支持的参数类型只有基础类型
    /// Boolean Char SByte Byte Int16 UInt16 Int32 UInt32 
    /// Int64 UInt64 Single Double Decimal DateTime String 
    /// </summary>
    /// <param name="context"></param>	
    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        context.Response.ContentEncoding = System.Text.Encoding.GetEncoding("gb2312");
        string data = string.Empty;
        
        try
        {
            //这两项必须有，如果没有就走异常失败流程
            string className = GetRequest("Class", context);
            string methodName = GetRequest("Method", context);

            Type classType = GetType(className);
            MethodInfo method = classType.GetMethod(methodName, BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase);
            if (method == null)
                throw new ArgumentException(string.Format("{0}中找不到函数{1}", className, methodName));

            object classObject = null;
            if (!method.IsStatic)
            {
                ConstructorInfo[] constructors = classType.GetConstructors();
                if (constructors == null || constructors.Length == 0)
                    throw new ArgumentException(string.Format("{0}中找不到构造", className));

                //这个版本不去探测选用哪个构造 但建议只用一个构造
                ConstructorInfo constructor = constructors[0];
                ParameterInfo[] constructorParameters = constructor.GetParameters();

                object[] constructorparameterValues = GetParameterValues(constructorParameters, context);
                classObject = constructor.Invoke(constructorparameterValues);
            }

            ParameterInfo[] methodParameters = method.GetParameters();
            object[] methodParameterValues = GetParameterValues(methodParameters, context);
            object resultObject = method.Invoke(classObject, methodParameterValues);
            if (resultObject != null)
                data = resultObject.ToString();
        }
        catch (Exception e)
        {
            //因为使用了Remoting, 会出现这种嵌套的异常	   
            if (e is System.Reflection.TargetInvocationException && e.InnerException != null)
                e = e.InnerException;

            Base.Log.WriteLine(e.Message);
            data = e.Message;
        }
        finally
        {
            context.Response.Write(data);
        }
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }

    string GetRequest(string key, HttpContext context)
    {
        string result = context.Request[key];
        if (result == null)
            throw new ArgumentNullException(key);

        Base.Log.WriteLine(string.Format("{0}===>{1}", key, result));

        return result;
    }

    object[] GetParameterValues(ParameterInfo[] parameters, HttpContext context)
    {
        object[] parameterValues = new object[parameters.Length];
        for (int i = 0; i < parameters.Length; ++i)
        {
            ParameterInfo parameter = parameters[i];
            parameterValues[i] = Convert.ChangeType(GetRequest(parameter.Name, context), parameter.ParameterType);

            //操作就使操作！不封装这种由多个功能的函数！！！！
            //if (value == null)//允许参数为空，具体就靠函数自己判断了
            //	parameterValues[i] = value;
            //else
            //	parameterValues[i] = Convert.ChangeType(value, parameter.ParameterType);  
        }
        return parameterValues;
    }

    Type GetType(string className)
    {
        foreach (Type type in m_Types)
        {
            if (string.Compare(className, type.FullName, true) == 0)
                return type;
        }


        Assembly[] assemblys = AppDomain.CurrentDomain.GetAssemblies();
        foreach (Assembly assembly in assemblys)
        {
            Type type = assembly.GetType(className, false, true);
            if (type == null)
                continue;

            m_Types.Add(type);
            return type;
        }

        throw new ArgumentException(string.Format("程序集中找不到类{0}", className));
    }

    static List<Type> m_Types = new List<Type>();
}